package com.example.munidingwei

import android.content.Context
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.provider.Settings
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

class MockLocationProvider(private val context: Context) {
    private val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    
    // 使用系统的GPS和NETWORK provider，让所有应用都能获取模拟位置
    private val providers = listOf(
        LocationManager.GPS_PROVIDER,
        LocationManager.NETWORK_PROVIDER
    )
    
    private val _isMockLocationEnabled = MutableStateFlow(false)
    val isMockLocationEnabled: StateFlow<Boolean> = _isMockLocationEnabled.asStateFlow()
    
    private val _isSystemMockEnabled = MutableStateFlow(false)
    val isSystemMockEnabled: StateFlow<Boolean> = _isSystemMockEnabled.asStateFlow()
    
    companion object {
        private const val TAG = "MockLocationProvider"
    }
    
    init {
        checkSystemMockSettings()
    }
    
    /**
     * 检查系统是否启用了Mock Location
     */
    fun checkSystemMockSettings() {
        val isEnabled = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Settings.Secure.getInt(context.contentResolver, Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0
        } else {
            Settings.Secure.getInt(context.contentResolver, Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0
        }
        _isSystemMockEnabled.value = isEnabled
    }
    
    /**
     * 检查是否有Mock Location权限
     * 注意：在Android 6.0+中，ACCESS_MOCK_LOCATION权限已被弃用
     * 现在主要通过开发者选项中的"允许模拟位置"来控制
     */
    fun hasMockLocationPermission(): Boolean {
        // 在Android 6.0+中，不再需要ACCESS_MOCK_LOCATION权限
        // 主要检查开发者选项是否启用
        return true
    }
    
    /**
     * 添加Mock Location Provider
     * 操作系统GPS和NETWORK provider，让所有应用都能获取模拟位置
     */
    fun addMockLocationProvider(): Boolean {
        return try {
            Log.d(TAG, "开始添加Mock Location Provider")
            
            if (!hasMockLocationPermission()) {
                Log.e(TAG, "没有Mock Location权限")
                return false
            }
            
            var successCount = 0
            // 为GPS和NETWORK provider添加测试模式
            providers.forEach { providerName ->
                try {
                    Log.d(TAG, "处理provider: $providerName")
                    
                    // 先移除已存在的测试provider
                    try {
                        locationManager.removeTestProvider(providerName)
                        Log.d(TAG, "移除旧的 $providerName 测试provider")
                    } catch (e: Exception) {
                        Log.d(TAG, "$providerName 没有旧的测试provider")
                    }
                    
                    // 添加测试provider
                locationManager.addTestProvider(
                        providerName,
                    false, // requiresNetwork
                    false, // requiresSatellite
                    false, // requiresCell
                    false, // hasMonetaryCost
                        true,  // supportsAltitude
                        true,  // supportsSpeed
                        true,  // supportsBearing
                        android.location.Criteria.POWER_LOW,
                        android.location.Criteria.ACCURACY_FINE
                    )
                    locationManager.setTestProviderEnabled(providerName, true)
                    Log.d(TAG, "✓ 成功为 $providerName 添加测试provider")
                    successCount++
                } catch (e: SecurityException) {
                    Log.e(TAG, "✗ SecurityException for $providerName: ${e.message}")
                    Log.e(TAG, "请确保已通过ADB授予权限: adb shell appops set com.example.munidingwei android:mock_location allow")
                } catch (e: Exception) {
                    Log.e(TAG, "✗ 为 $providerName 添加测试provider失败: ${e.message}")
                    e.printStackTrace()
                }
            }
            
            val success = successCount > 0
            _isMockLocationEnabled.value = success
            
            Log.d(TAG, "Mock Location Provider设置完成: $successCount/${providers.size} 成功")
            success
        } catch (e: Exception) {
            Log.e(TAG, "添加Mock Location Provider发生错误: ${e.message}")
            e.printStackTrace()
            false
        }
    }
    
    /**
     * 移除Mock Location Provider
     */
    fun removeMockLocationProvider() {
        try {
            Log.d(TAG, "开始移除Mock Location Provider")
            
            var successCount = 0
            providers.forEach { providerName ->
                try {
                    // 先禁用测试provider
                    locationManager.setTestProviderEnabled(providerName, false)
                    Log.d(TAG, "禁用 $providerName 测试provider")
                    
                    // 移除测试provider
                    locationManager.removeTestProvider(providerName)
                    Log.d(TAG, "✓ 成功移除 $providerName 测试provider")
                    successCount++
                } catch (e: IllegalArgumentException) {
                    Log.d(TAG, "$providerName 测试provider不存在，已经清理")
                } catch (e: Exception) {
                    Log.e(TAG, "✗ 移除 $providerName 失败: ${e.message}")
                    e.printStackTrace()
                }
            }
            
            _isMockLocationEnabled.value = false
            Log.d(TAG, "Mock Location Provider移除完成: $successCount/${providers.size} 成功")
        } catch (e: Exception) {
            Log.e(TAG, "移除Mock Location Provider发生错误: ${e.message}")
            e.printStackTrace()
        }
    }
    
    /**
     * 设置Mock位置
     * 同时设置GPS和NETWORK provider，确保所有应用都能获取
     */
    fun setMockLocation(latitude: Double, longitude: Double, accuracy: Float = 5.0f) {
        if (!_isMockLocationEnabled.value) {
            Log.w(TAG, "Mock Location未启用，无法设置位置")
            return
        }
        
        Log.d(TAG, "设置模拟位置: lat=$latitude, lng=$longitude, accuracy=$accuracy")
        
        try {
            val currentTime = System.currentTimeMillis()
            val elapsedTime = System.nanoTime()
            
            var successCount = 0
            providers.forEach { providerName ->
                try {
                    val mockLocation = Location(providerName).apply {
                this.latitude = latitude
                this.longitude = longitude
                this.accuracy = accuracy
                        this.time = currentTime
                        this.elapsedRealtimeNanos = elapsedTime
                        
                        // 设置额外的GPS信息，让模拟更真实
                        if (providerName == LocationManager.GPS_PROVIDER) {
                            this.altitude = 0.0
                            this.bearing = 0.0f
                            this.speed = 0.0f
                        }
                    }
                    
                    locationManager.setTestProviderLocation(providerName, mockLocation)
                    Log.d(TAG, "✓ 成功为 $providerName 设置模拟位置")
                    successCount++
                } catch (e: SecurityException) {
                    Log.e(TAG, "✗ SecurityException for $providerName: ${e.message}")
                } catch (e: Exception) {
                    Log.e(TAG, "✗ 为 $providerName 设置位置失败: ${e.message}")
                    e.printStackTrace()
                }
            }
            
            Log.d(TAG, "模拟位置设置完成: $successCount/${providers.size} 成功")
        } catch (e: Exception) {
            Log.e(TAG, "设置模拟位置发生错误: ${e.message}")
            e.printStackTrace()
        }
    }
    
    /**
     * 停止Mock位置
     */
    fun stopMockLocation() {
        removeMockLocationProvider()
    }
    
    /**
     * 检查是否正在使用Mock位置
     */
    fun isUsingMockLocation(): Boolean {
        return _isMockLocationEnabled.value
    }
    
    /**
     * 获取系统Mock设置状态
     */
    fun getSystemMockStatus(): String {
        return when {
            !_isSystemMockEnabled.value -> "需要在开发者选项中启用'允许模拟位置'"
            else -> "系统Mock设置正常"
        }
    }
}
